#include "glare.math.NumericUtils.h"
#include "glare.math.asm_math.h"

namespace Glare {

	const Real NumericUtils::LOG2 = log(Real(2.0));
	const Real NumericUtils::POS_INFINITY = std::numeric_limits<Real>::infinity();
	const Real NumericUtils::NEG_INFINITY = -std::numeric_limits<Real>::infinity();

	NumericUtils::RandomValueProvider* NumericUtils::mRandProvider = NULL;


	//-----------------------------------------------------------------------
	bool NumericUtils::RealEqual( Real a, Real b, Real tolerance )
	{
		if (fabs(b-a) <= tolerance)
			return true;
		else
			return false;
	}
	//-----------------------------------------------------------------------
	Real NumericUtils::Sign (Real fValue)
	{
		if ( fValue > 0.0 )
			return 1.0;

		if ( fValue < 0.0 )
			return -1.0;

		return 0.0;
	}
	//-----------------------------------------------------------------------
	Real NumericUtils::InvSqrt(Real fValue)
	{
		return Real(asm_rsq(fValue));
	}
	//-----------------------------------------------------------------------
	int NumericUtils::ISign (int iValue)
	{
		return ( iValue > 0 ? +1 : ( iValue < 0 ? -1 : 0 ) );
	}
	//-----------------------------------------------------------------------
	Real NumericUtils::UnitRandom ()
	{
		if (mRandProvider)
			return mRandProvider->getRandomUnit();
		else return asm_rand() / asm_rand_max();
	}

	//-----------------------------------------------------------------------
	Real NumericUtils::RangeRandom (Real fLow, Real fHigh)
	{
		return (fHigh-fLow)*UnitRandom() + fLow;
	}

	//-----------------------------------------------------------------------
	Real NumericUtils::SymmetricRandom ()
	{
		return 2.0f * UnitRandom() - 1.0f;
	}

	//-----------------------------------------------------------------------
	void NumericUtils::SetRandomValueProvider(RandomValueProvider* provider)
	{
		mRandProvider = provider;
	}
}
